/*
 * @Date: 2022-01-25 14:29:20
 * @LastEditors: Jason Chen
 * @LastEditTime: 2022-12-05 16:10:52
 * @FilePath: /changeDbPassword/server/plugin/db/main.go
 */
package db

import (
	"database/sql"
	"fmt"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/flipped-aurora/gin-vue-admin/server/plugin/db/model"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"

	_ "github.com/godror/godror"
)

var ExamplePlugin = new(pluginExample)

type pluginExample struct{}

func CreatePlugin() *pluginExample {

	return &pluginExample{}
}

func (*pluginExample) Register(group *gin.RouterGroup) {
	//如需细分权限 可以在此处use中间件 gva项目包名已改为github模式
	//所以整个plugin可以直接独立到外层开启为新的项目 然后用包的形式导入也是可以完整运行的
	// 例:
	/*
		group.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()).GET("hello", func(context *gin.Context) {
			context.JSON(200, "hello world")
		})
	*/
	group.POST("changePassword", func(context *gin.Context) {
		var singleReq model.ChangeDbPasswordRequest
		_ = context.ShouldBindJSON(&singleReq)

		// 判断数据库类型
		if singleReq.DbType == model.DbTypeEnum_Oracel { // 修改 oracel 密码
			connectionStr := fmt.Sprintf(`user="%v" password="%v" connectString="%v:%v/%v"`,
				singleReq.DbUserName, singleReq.Password, singleReq.DbHost, singleReq.DbPort, singleReq.InstanceName)
			oracelDb, err := sql.Open("godror", connectionStr)
			if err != nil {
				context.JSON(500, err.Error())
				return
			}
			err = oracelDb.Ping()
			if err != nil {
				context.JSON(500, err.Error())
				return
			}

			sql := fmt.Sprintf("ALTER USER %v IDENTIFIED BY %v;", singleReq.DbUserName, singleReq.NewPassword)
			stmt, err := oracelDb.Prepare(sql)
			if err != nil {
				context.JSON(500, err.Error())
				return
			}
			defer stmt.Close()
		} else if singleReq.DbType == model.DbTypeEnum_Mysql { // mysql 密码修改
			dbURI := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8&parseTime=true",
				singleReq.DbUserName,
				singleReq.Password,
				singleReq.DbHost,
				singleReq.DbPort,
				singleReq.InstanceName)
			mysqlConfig := mysql.Config{
				DSN:                       dbURI, // DSN data source name
				DefaultStringSize:         191,   // string 类型字段的默认长度
				SkipInitializeWithVersion: false, // 根据版本自动配置
			}
			dialector := mysql.New(mysqlConfig)
			conn, err := gorm.Open(dialector, &gorm.Config{})
			if err != nil {
				context.JSON(500, err.Error())
				return
			}
			sqlDB, err := conn.DB()
			if err != nil {
				context.JSON(500, err.Error())
				return
			}
			sql := fmt.Sprintf("set password for %v@localhost = password(‘%v’)",
				singleReq.DbUserName, singleReq.NewPassword)
			_, err = sqlDB.Exec(sql)
			if err != nil {
				context.JSON(500, err.Error())
				return
			}
		}

		context.JSON(200, "database password changed!")
	})

	// 获取数据库列表
	group.POST("getList", func(context *gin.Context) {
		list := []model.DatabaseModel{}
		err := global.GVA_DB.Find(&list).Error
		if err != nil {
			context.JSON(500, err.Error())
			return
		}

		resp := model.PageResult{
			List:     list,
			Total:    len(list),
			Page:     1,
			PageSize: 10,
		}
		response.OkWithDetailed(resp, "获取成功", context)
	})
}

func (*pluginExample) RouterPath() string {
	return "db"
}
